/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.sales.hancadso.client.presenter.grid;

import br.com.sales.generics.client.presenter.events.ShowLoadingEvent;
import br.com.sales.generics.client.request.HannaRequestCallback;
import static br.com.sales.hancadso.client.presenter.consts.HanCadSOConsts.HEADER_ROW_INDEX;
import br.com.sales.hancadso.client.presenter.events.RemoveEditingEvent;
import br.com.sales.hancadso.client.presenter.events.RemoveEditingHandler;
import br.com.sales.hancadso.client.presenter.events.SaveRecordOnClickEvent;
import br.com.sales.hancadso.client.presenter.events.SaveRecordOnClickHandler;
import br.com.sales.hancadso.client.presenter.grid.menuitem.AdvClickListener;
import br.com.sales.hancadso.client.service.HanCadSOService;
import com.google.gwt.core.client.JsonUtils;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONNumber;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 *
 * @author v
 */
public class HanCadSOGrid extends FlexTable
        implements Event.NativePreviewHandler, SaveRecordOnClickHandler, RemoveEditingHandler {

    private boolean isEditing = false;
    private int rowEditing;
    private JSONObject record;
    private final Map<Object, JSONValue> listRecordsSubItem = new LinkedHashMap<>();
    private final Map<Object, JSONObject> listRecords = new LinkedHashMap<>();
    private final HanCadSOService service;
    private final EventBus eventBus;
    @Inject
    private AdvClickListener listener;

    @Inject
    public HanCadSOGrid(EventBus eventBus, HanCadSOService service) {
        this.service = service;
        this.eventBus = eventBus;
        createGrid();
        Event.addNativePreviewHandler(this);
        sinkEvents(Event.ONDBLCLICK | Event.ONCONTEXTMENU | Event.ONMOUSEUP);
        addContextMenuEventListener(RootPanel.getBodyElement());
        eventBus.addHandler(SaveRecordOnClickEvent.TYPE, this);
        eventBus.addHandler(RemoveEditingEvent.TYPE, this);
    }

    public final void createGrid() {
        this.insertRow(HEADER_ROW_INDEX);
        this.getRowFormatter().addStyleName(HEADER_ROW_INDEX, "flextable-header");

        addColumn("Cód.");
        addColumn("Data");
        addColumn("Solicitação");
        addColumn("Aprovação");
        addColumn("Encerramento");
        addColumn("Cancelamento");
        addColumn("Solicitante");

        this.setCellSpacing(0);
        this.addStyleName("flexttable-product");
        this.getColumnFormatter().setWidth(1, "145px");
        this.getColumnFormatter().setWidth(2, "145px");
        this.getColumnFormatter().setWidth(3, "145px");
        this.getColumnFormatter().setWidth(4, "145px");
        this.getColumnFormatter().setWidth(5, "145px");
        this.getColumnFormatter().setWidth(6, "200px");
    }

    @Override
    public void onPreviewNativeEvent(Event.NativePreviewEvent event) {

    }

    protected final native void addContextMenuEventListener(Element elem) /*-{
     elem.oncontextmenu = function(e) {
     return false; // TODO: only return false if control key down...
     };
     }-*/;

    @Override
    public void onBrowserEvent(Event event) {
        super.onBrowserEvent(event);
        Element td = getEventTargetCell(event);
        if (td == null) {
            return;
        }
        Element tr = DOM.getParent(td);
        Element body = DOM.getParent(tr);
        int row = DOM.getChildIndex(body, tr);

        final Object sequence = getText(row, 0);
        int type = DOM.eventGetType(event);
        switch (type) {
            case Event.ONDBLCLICK: {
                if (!listRecordsSubItem.containsKey(sequence)) {
                    service.getDataSubItem(Long.parseLong(sequence.toString()), new HannaRequestCallback() {

                        @Override
                        public void onResponseReceived(Request request, Response response) {
                            JSONObject jSONObject = new JSONObject(JsonUtils.safeEval(response.getText()));
                            listRecordsSubItem.put(sequence, jSONObject);
                            show(jSONObject);
                        }
                    });
                } else {
                    show(listRecordsSubItem.get(sequence).isObject());
                }
                break;
            }
            case Event.ONCONTEXTMENU: {
                event.preventDefault();
                event.stopPropagation();
                break;
            }
            case Event.ONMOUSEUP: {
                if (DOM.eventGetButton(event) == Event.BUTTON_RIGHT) {
                    setIsEditing(true);
                    rowEditing = row;
                    listener.onRightClick(listRecords.get(sequence), event);
                }
                break;
            }
        }
    }

    @Override
    public void adjust() {
        setIsEditing(false);
        rowEditing = 0;
    }

    private void show(JSONObject record) {
        SubItemRequestPopUp popup = new SubItemRequestPopUp();
        popup.addValueTogrid(record);
        popup.show();
    }

    public void setIsEditing(boolean isEditing) {
        this.isEditing = isEditing;
        if (!isEditing) {
            rowEditing = 0;
        }
    }

    public void update(Map items) {
        eventBus.fireEvent(new ShowLoadingEvent(true));
        service.getDateGrid(items, new HannaRequestCallback() {

            @Override
            public void onResponseReceived(Request request, Response response) {
                clear();
                isEditing = false;
                record = new JSONObject(JsonUtils.safeEval(response.getText()));
                addValueTogrid();
                eventBus.fireEvent(new ShowLoadingEvent(false));
            }
        });
    }

    @Override
    public void clear() {
        int rouCount = getRowCount();
        for (int i = rouCount - 1; i > 0; i--) {
            removeRow(i);
        }
    }

    private void addValueTogrid() {
        int column = 0;
        int index = getRowCount();
        for (String item : record.keySet()) {
            Object sequence = convert(record.get(item).isObject().get("SEQ"));
            listRecords.put(sequence, record.get(item).isObject());
            addRow(sequence, index, column++);
            addRow(convert(record.get(item).isObject().get("DT_REGISTRO")), index, column++);
            addRow(convert(record.get(item).isObject().get("DT_SOLICITACAO")), index, column++);
            addRow(convert(record.get(item).isObject().get("DT_APROVACAO")), index, column++);
            addRow(convert(record.get(item).isObject().get("DT_ENCERRAMENTO")), index, column++);
            addRow(convert(record.get(item).isObject().get("DT_CANCELAMENTO")), index, column++);
            addRow(convert(record.get(item).isObject().get("NM_PESSOA_FISICA")), index, column++);
            column = 0;
            index++;
        }
    }

    public void addValueTogrid(JSONObject record) {
        int column = 0;
        int index = isEditing ? rowEditing : getRowCount();
        Object sequence = convert(record.get("SEQ"));
        listRecords.put(sequence, record);
        addRow(sequence, index, column++);
        addRow(convert(record.get("DT_REGISTRO")), index, column++);
        addRow(convert(record.get("DT_SOLICITACAO")), index, column++);
        addRow(convert(record.get("DT_APROVACAO")), index, column++);
        addRow(convert(record.get("DT_ENCERRAMENTO")), index, column++);
        addRow(convert(record.get("DT_CANCELAMENTO")), index, column++);
        addRow(convert(record.get("NM_PESSOA_FISICA")), index, column++);
        setIsEditing(false);
    }

    @Override
    public void onClickSave(JSONObject recordEditing) {
        addValueTogrid(recordEditing);
    }

    public boolean isEditing() {
        return isEditing;
    }

    private Object convert(JSONValue value) {
        if (value == null) {
            return "";
        }
        if (value instanceof JSONString) {
            return value.isString().stringValue();
        } else if (value instanceof JSONNumber) {
            return value.isNumber().toString();
        }
        return "";
    }

    private void addRow(Object value, int row, int cell) {
        if (isEditing) {
            Widget widget = createCellWidget(value);
            setWidget(rowEditing, cell, widget);
            getCellFormatter().addStyleName(rowEditing, cell, "flextable-cell");
        } else {
            Widget widget = createCellWidget(value);
            setWidget(row, cell, widget);
            getCellFormatter().addStyleName(row, cell, "flextable-cell");
        }
    }

    private Widget createCellWidget(Object cellObject) {
        Widget widget;

        if (cellObject instanceof Widget) {
            widget = (Widget) cellObject;
        } else {
            widget = new Label(cellObject.toString());
        }
        return widget;
    }

    private void addColumn(Object columnHeading) {
        Widget widget = createCellWidget(columnHeading);
        int cell = getCellCount(HEADER_ROW_INDEX);

        widget.addStyleName("flextable-column-label");

        setWidget(HEADER_ROW_INDEX, cell, widget);

        getCellFormatter().addStyleName(HEADER_ROW_INDEX, cell, "flextable-column-label-cell");
    }
}
